package com.lincoln.framework.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 数字工具类型
 * 
 * @author rubekid
 * 
 */
public class NumberUtils {
	private final static String[] GROUP_UNITS = { "", "万", "亿", "兆" };
	private final static String[] BASE_UNITS = { "", "十", "百", "千" };
	private final static char[] SIMPLIFIED_NUMBERIC = { '零', '一', '二', '三', '四', '五', '六', '七', '八', '九' };
	private final static char[] TRADITIONAL_NUMBERIC = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' };

	/**
	 * 转为中文数字
	 * 
	 * @param number
	 *            数值
	 * @param isTraditional
	 *            是否转为繁体
	 * @return
	 */
	public static String toChinese(long number, boolean isTraditional) {
		char[] numberic = isTraditional ? TRADITIONAL_NUMBERIC : SIMPLIFIED_NUMBERIC;
		if (number == 0) {
			return String.valueOf(numberic[0]);
		}
		String str = String.valueOf(number);
		char[] numbers = str.toCharArray();
		int len = str.length();
		// 统计连续出现的0
		int zeroCount = 0;

		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < len; i++) {
			int value = Integer.parseInt(String.valueOf(numbers[i]));
			int index = len - i - 1;
			// 在分组中的下标
			int _index = index % 4;
			if (value == 0) {
				zeroCount++;
				if ((_index == 0 && zeroCount < 4) || (index % 8 == 0 && zeroCount < 8)) {
					stringBuffer.append(getGroupUnit(index));
					zeroCount = 0;
				}
			} else {
				if (zeroCount > 0) {
					stringBuffer.append(numberic[0]);
				}
				if (_index == 0) {
					stringBuffer.append(numberic[value] + BASE_UNITS[_index] + getGroupUnit(index));
					zeroCount = 0;
				} else {
					// 调整以“一十”开头的不需要出现“一” 如：100000 读“十万”而不是“一十万”
					if (_index == 1 && i == 0 && value == 1) {
						stringBuffer.append(BASE_UNITS[_index]);
					} else {
						stringBuffer.append(numberic[value] + BASE_UNITS[_index]);
					}

				}
				zeroCount = 0;
			}

		}
		return stringBuffer.toString();
	}

	/**
	 * 转为中文数字
	 * 
	 * @param number
	 *            数值
	 * @return
	 */
	public static String toChinese(long number) {
		return toChinese(number, false);
	}

	/**
	 * 转为中文数字
	 * 
	 * @param number
	 *            数值
	 * @param isTraditional
	 *            是否转为繁体
	 */
	public static String toChinese(int number, boolean isTraditional) {
		return toChinese((long) number, isTraditional);
	}

	/**
	 * 转为中文数字
	 * 
	 * @param number
	 *            数值
	 */
	public static String toChinese(int number) {
		return toChinese(number, false);
	}

	/**
	 * 获取分组单位
	 * 
	 * @param index
	 * @return
	 */
	private static String getGroupUnit(int index) {
		String groupUnit = GROUP_UNITS[(index / 4) % 2];
		if (index % 8 == 0 && index > 0) {
			groupUnit += GROUP_UNITS[(index / 8) + 1];
		}
		return groupUnit;
	}

	/**
	 * 浮点数相加
	 * 
	 * @param arg1
	 * @param arg2
	 * @return double
	 */
	public static double add(double arg1, double arg2) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.add(new BigDecimal(arg2)).doubleValue();
	}

	/**
	 * 浮点数相减
	 * 
	 * @param arg1
	 * @param arg2
	 * @return double
	 */
	public static double sub(double arg1, double arg2) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.subtract(new BigDecimal(arg2)).doubleValue();
	}

	/**
	 * 计算浮点数相除，保留两位小数，向上取余
	 * 
	 * @param arg1
	 *            分子
	 * @param arg2
	 *            分母
	 * @return double
	 */
	public static double divide(double arg1, double arg2) {
		return divide(arg1, arg2, 2, RoundingMode.HALF_UP);
	}

	/**
	 * 计算浮点数相除
	 * 
	 * @param arg1
	 *            分子
	 * @param arg2
	 *            分母
	 * @param scale
	 *            保留小数
	 * @param mode
	 *            取余方式
	 * @return double
	 */
	public static double divide(double arg1, double arg2, int scale) {
		return divide(arg1, arg2, scale, RoundingMode.HALF_UP);
	}

	/**
	 * 计算浮点数相除
	 * 
	 * @param arg1
	 *            分子
	 * @param arg2
	 *            分母
	 * @param scale
	 *            保留小数
	 * @param mode
	 *            取余方式
	 * @return double
	 */
	public static double divide(double arg1, double arg2, int scale, RoundingMode mode) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.divide(new BigDecimal(arg2), scale, mode).doubleValue();
	}

	/**
	 * 计算浮点数相乘
	 * 
	 * @param arg1
	 * @param arg2
	 * @return double
	 */
	public static double multiply(double arg1, double arg2) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.multiply(new BigDecimal(arg2)).doubleValue();
	}

	/**
	 * 浮点数相加
	 * 
	 * @param arg1
	 * @param arg2
	 * @return float
	 */
	public static float add(float arg1, float arg2) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.add(new BigDecimal(arg2)).floatValue();
	}

	/**
	 * 浮点数相减
	 * 
	 * @param arg1
	 * @param arg2
	 * @return float
	 */
	public static float sub(float arg1, float arg2) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.subtract(new BigDecimal(arg2)).floatValue();
	}

	/**
	 * 计算浮点数相除，保留两位小数，向上取余
	 * 
	 * @param arg1
	 *            分子
	 * @param arg2
	 *            分母
	 * @return float
	 */
	public static float divide(float arg1, float arg2) {
		return divide(arg1, arg2, 2, RoundingMode.HALF_UP);
	}

	/**
	 * 计算浮点数相除
	 * 
	 * @param arg1
	 *            分子
	 * @param arg2
	 *            分母
	 * @param scale
	 *            保留小数
	 * @param mode
	 *            取余方式
	 * @return float
	 */
	public static float divide(float arg1, float arg2, int scale, RoundingMode mode) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.divide(new BigDecimal(arg2), scale, mode).floatValue();
	}

	/**
	 * 计算浮点数相乘
	 * 
	 * @param arg1
	 * @param arg2
	 * @return float
	 */
	public static float multiply(float arg1, float arg2) {
		BigDecimal bigDecimal = new BigDecimal(arg1);
		return bigDecimal.multiply(new BigDecimal(arg2)).floatValue();
	}

	/**
	 * 浮点数按格式转化字符串,保留两位有效小数
	 * 
	 * @param formatValue
	 * @return String
	 */
	public static String decimalFormat(double formatValue) {
		return decimalFormat("#0.00", formatValue);
	}

	/**
	 * 浮点数按格式转化字符串
	 * 
	 * @param formatString
	 * @param formatValue
	 * @return String
	 */
	public static String decimalFormat(String formatString, double formatValue) {
		return new DecimalFormat(formatString).format(formatValue);
	}
	
	/**
	 * 字符串数字数组转换integer类型
	 * 
	 * @param strings
	 * @return
	 * List<Integer>
	 */
	public static List<Integer> toIntegerList(String[] strings) {
		List<Integer> integers = new ArrayList<Integer>();
		if(strings != null && strings.length > 0) {
			for (String str : strings) {
				if(ParameterChecker.isNumber(str)) {
					integers.add(Integer.valueOf(str));
				}
			}
		}
		return integers;
	}
	
	public static Integer[] toInteger(int[] values){
		if(values.length == 0){
			return null;
		}
		Integer[] result = new Integer[values.length];
		for(int i=0; i< values.length; i++){
			result[i] = values[i];
		}
		return result;
	}

	public static int String2Int(String str){
		int result = 0;
		try{
			result = Integer.parseInt(str);
			return result;
		}catch (Exception e){
			return 0;
		}
	}
}
